#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>

const int BufferSize = 5;

class SharedBuffer {
public:
    void produce(int value) {
        std::unique_lock<std::mutex> lock(mutex);

        // 等待缓冲区非满
        notFull.wait(lock, [this] { return buffer.size() < BufferSize; });

        buffer.push(value);
        std::cout << "Produced: " << value << std::endl;

        // 通知缓冲区非空
        notEmpty.notify_all();
    }

    int consume() {
        std::unique_lock<std::mutex> lock(mutex);

        // 等待缓冲区非空
        notEmpty.wait(lock, [this] { return !buffer.empty(); });

        int value = buffer.front();
        buffer.pop();
        std::cout << "Consumed: " << value << std::endl;

        // 通知缓冲区非满
        notFull.notify_all();

        return value;
    }

private:
    std::queue<int> buffer;
    std::mutex mutex;
    std::condition_variable notFull;
    std::condition_variable notEmpty;
};

void producer(SharedBuffer& buffer) {
    for (int i = 0; i < 10; ++i) {
        buffer.produce(i);
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
    }
}

void consumer(SharedBuffer& buffer) {
    for (int i = 0; i < 10; ++i) {
        int value = buffer.consume();
        std::this_thread::sleep_for(std::chrono::milliseconds(300));
    }
}

int main() {
    SharedBuffer buffer;

    std::thread producerThread(producer, std::ref(buffer));
    std::thread consumerThread(consumer, std::ref(buffer));

    producerThread.join();
    consumerThread.join();

    return 0;
}